package com.db.mongoDb;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.bson.types.ObjectId;

import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.Mongo;
import com.mongodb.gridfs.GridFS;
import com.mongodb.gridfs.GridFSDBFile;
import com.mongodb.gridfs.GridFSFile;
import com.util.file.HashFile;

public class MongoDbUtil {
	private static Mongo mongo;
	private static DB imgDB;
	private static final String MONGO_DB_ADDRESS = "localhost";
	private static final int MONGO_DB_PORT = 27017;
	private static final String MONGO_DB_USERNAME = "";
	private static final String MONGO_DB_PASSWORD = "";
	private static final String MONGO_DB_IMG_DBNAME = "zu";
	private static final String MONGO_DB_RESOURCE_FILE = "mongo.properties";

	private static String collName = "image";
	private static DB db;
	private static String dbName;
	/**
	 * Mongo��ݿ����
	 */
	private static Map<String, String> cfgMap = new HashMap<String, String>();

	private static Hashtable<String, DB> mongoDBs = new Hashtable<String, DB>();

	static {

		init();
		dbName = MONGO_DB_IMG_DBNAME;
		db = getDBByName(dbName);
	}

	private static void init() {

		initCfgMap();
		try {
			String address = cfgMap.get("mongo.db.address");
			int port = Integer.parseInt(cfgMap.get("mongo.db.port").toString());
			String dbName = cfgMap.get("mongo.db.img.dbname");
			String username = cfgMap.get("mongo.db.username");
			String password = cfgMap.get("mongo.db.password");
			mongo = new Mongo(address, port);
			imgDB = mongo.getDB(dbName);
			imgDB.addUser(username, password.toCharArray());
			mongoDBs.put(dbName, imgDB);
		} catch (IOException e) {
			System.out.println("����Mongo�����ļ�ʧ��!");
			e.printStackTrace();
		}
	}

	private static void initCfgMap() {
		File file = getConfigFile();
		if (file != null) {
			Properties p = new Properties();
			try {
				p.load(new FileInputStream(file));
				for (Enumeration enu = p.propertyNames(); enu.hasMoreElements();) {
					String key = (String) enu.nextElement();
					String value = (String) p.getProperty(key);
					cfgMap.put(key, value);
				}
			} catch (IOException e) {
				System.out.println("!");
				e.printStackTrace();
			}
		} else {
			cfgMap.put("mongo.db.address", MONGO_DB_ADDRESS);
			cfgMap.put("mongo.db.port", String.valueOf(MONGO_DB_PORT));
			cfgMap.put("mongo.db.username", MONGO_DB_USERNAME);
			cfgMap.put("mongo.db.password", MONGO_DB_PASSWORD);
			cfgMap.put("mongo.db.img.dbname", MONGO_DB_IMG_DBNAME);
		}
	}

	public static File getConfigFile() {
		String path = MongoDBConfig.class.getResource("/").getPath();
		System.out.println(path);
		String fileName = path + MONGO_DB_RESOURCE_FILE;
		File file = new File(fileName);
		if (file.exists()) {
			return file;
		}
		return null;
	}

 
	public static Mongo getMongo() {
		return mongo;
	}

 
	public static DB getImgDB() {
		return imgDB;
	}

	public static List<String> getDBNames() {
		return mongo.getDatabaseNames();
	}
 
	public static DB getDBByName(String dbName) {
		DB db = mongo.getDB(dbName);
		if (!mongoDBs.contains(db)) {
			db.addUser(cfgMap.get("mongo.db.username"),
					cfgMap.get("mongo.db.password").toCharArray());
			mongoDBs.put(dbName, db);
		}
		return db;
	}

	public static Object saveImage(InputStream file) {
		GridFS f = getGridFS(getDBByName(MONGO_DB_IMG_DBNAME));
		String md5 = HashFile.getHash(file, "MD5");
		GridFSFile mongofile = f.createFile(file);
		mongofile.put("uploadDate", new Date());
		mongofile.put("filename", md5);
		mongofile.put("id", md5);
		mongofile.put("md5", md5);
		mongofile.save();
		return md5;
	}

	/**
	 * 
	 * @param file
	 * @return
	 */
	public static Object saveImage(File file) {
		GridFS f = getGridFS(getDBByName(MONGO_DB_IMG_DBNAME));

		try {
			String md5 = HashFile.getHash(file, "MD5");
			GridFSFile mongofile = f.createFile(file);
			mongofile.put("uploadDate", new Date());
			mongofile.put("filename", md5);
			mongofile.put("id", md5);
			mongofile.put("md5", md5);
			mongofile.save();
			return md5;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}

	}

	/**
	 * 
	 * @param file
	 * @return
	 */
	public static Object saveImage(String file) {
		File _file = new File(file);
		if (_file.exists()) {
			return saveImage(_file);
		} else {
			return null;
		}
	}

	public static GridFS getGridFS(DB db) {
		GridFS gridFS = new GridFS(db);
		return gridFS;
	}

	public static GridFS getGridFS() {
		return getGridFS(getDBByName(MONGO_DB_IMG_DBNAME));
	}

	/**
	 * read message
	 * 
	 * @param filename
	 * @return
	 */
	public InputStream getFileInputStream(String filename) {
		return getGridFS().findOne(filename).getInputStream();
	}

	public static long getFileCount() {
		return getGridFS().getFileList().count();
	}

	public List<GridFSDBFile> getAllFiles() {
		return getGridFS().find(new BasicDBObject());
	}

	public void removeFile(String filename) {
		getGridFS().remove(filename);
	}

	public void removeFile(BasicDBObject query) {
		getGridFS().remove(query);
	}

	public void removeFile(ObjectId id) {
		getGridFS().remove(id);
	}

	public static void removeAllFile() {
	 
		getGridFS().remove(new BasicDBObject());
	}

	public List<String> getAllDBNames() {
		return MongoDBConfig.getDBNames();
	}

	public GridFSDBFile findFirstFile(Map<String, Object> map) {
		return getGridFS().findOne(map2Obj(map));
	}

	public DBObject map2Obj(Map<String, Object> map) {
		DBObject obj = new BasicDBObject();
		obj.putAll(map);
		return obj;
	}

	public static void insert(Map<String, Object> map) {
		DBObject obj = new BasicDBObject();
		obj.putAll(map);
		getCollection().insert(obj);
	}

	public static DBCollection getCollection() {
		return db.getCollection(collName);
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {

	}

}
